package com.aek.ebey.sys.service.impl;

import com.aek.ebey.sys.core.BeanMapper;
import com.aek.ebey.sys.mapper.SysRoleUserMapper;
import com.aek.ebey.sys.model.SysRole;
import com.aek.ebey.sys.model.SysRoleUser;
import com.aek.ebey.sys.model.SysTenant;
import com.aek.ebey.sys.model.SysUser;
import com.aek.ebey.sys.model.vo.SysRoleVo;
import com.aek.ebey.sys.model.vo.SysTenantRoleVo;
import com.aek.ebey.sys.service.SysRoleService;
import com.aek.ebey.sys.service.SysRoleUserService;
import com.aek.ebey.sys.service.SysTenantService;
import com.aek.ebey.sys.service.SysUserService;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.google.common.collect.Lists;
import com.aek.common.core.base.BaseServiceImpl;

import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * <p>
 * 用户角色关联表 服务实现类
 * </p>
 *
 * @author aek
 * @since 2017-05-06
 */
@Service
@Transactional
public class SysRoleUserServiceImpl extends BaseServiceImpl<SysRoleUserMapper, SysRoleUser>
		implements SysRoleUserService {

	@Autowired
	private SysUserService userService;

	@Autowired
	private SysTenantService tenantService;

	@Autowired
	private SysRoleService roleService;

	@Override
	@Transactional(readOnly = true)
	public List<SysRoleUser> findByRoleId(Long roleId) {
		Wrapper<SysRoleUser> wrapper = new EntityWrapper<SysRoleUser>();
		wrapper.eq("role_id", roleId).eq("enable", true);
		return this.selectList(wrapper);
	}

	@Override
	public void deactivateRoleUserByRoleId(Long roleId) {
		List<SysRoleUser> roleUsers = this.findByRoleId(roleId);

		if (CollectionUtils.isNotEmpty(roleUsers)) {
			for (SysRoleUser roleUser : roleUsers) {
				roleUser.setEnable(false);
			}
		}
		if (CollectionUtils.isNotEmpty(roleUsers)) {
			this.updateBatchById(roleUsers);
		}
	}

	@Override
	public void recoverRoleUserByRoleId(Long roleId) {
		Wrapper<SysRoleUser> wrapper = new EntityWrapper<SysRoleUser>();
		wrapper.eq("role_id", roleId).eq("enable", false);
		List<SysRoleUser> roleUsers = this.selectList(wrapper);

		for (SysRoleUser roleUser : roleUsers) {
			roleUser.setEnable(true);
		}
		if (CollectionUtils.isNotEmpty(roleUsers)) {
			this.updateBatchById(roleUsers);
		}
	}

	@Override
	@Transactional(readOnly = true)
	public List<SysUser> findUserByRoleIdAndStatus(Long roleId, Boolean status) {
		Wrapper<SysRoleUser> wrapper = new EntityWrapper<SysRoleUser>();
		wrapper.eq("role_id", roleId).eq("enable", true);

		List<SysRoleUser> roleUsers = this.selectList(wrapper);
		List<SysUser> users = Lists.newArrayList();

		for (SysRoleUser roleUser : roleUsers) {
			SysUser user = this.userService.selectById(roleUser.getUserId());

			// 按条件添加结果集
			if (user != null && !user.getDelFlag()) {
				if (status == null) {
					users.add(user);

				} else {
					if (status == user.getEnable()) {
						users.add(user);
					}
				}
			}
		}
		return users;
	}

	@Override
	@Transactional(readOnly = true)
	public List<SysTenantRoleVo> findRoleByUserId(Long userId) {
		List<SysTenantRoleVo> tenantRoles = Lists.newArrayList();

		Wrapper<SysRoleUser> wrapper = new EntityWrapper<SysRoleUser>();
		wrapper.eq("user_id", userId).eq("enable", true).groupBy("tenant_id").orderBy("tenant_id");
		List<SysRoleUser> roleUsers = this.selectList(wrapper);

		for (SysRoleUser roleUser : roleUsers) {
			SysTenantRoleVo tenantRole = new SysTenantRoleVo();

			SysTenant tenant = this.tenantService.selectById(roleUser.getTenantId());
			tenantRole.setTenantId(tenant.getId());
			tenantRole.setTenantName(tenant.getName());

			List<SysRoleVo> roles = this.findByTenantIdAndUserId(roleUser.getTenantId(), userId);
			tenantRole.setRoles(roles);
			tenantRoles.add(tenantRole);
		}
		return tenantRoles;
	}

	@Override
	@Transactional(readOnly = true)
	public List<SysRoleVo> findByTenantIdAndUserId(Long tenantId, Long userId) {
		Wrapper<SysRoleUser> wrapper = new EntityWrapper<SysRoleUser>();
		wrapper.eq("tenant_id", tenantId).eq("user_id", userId).eq("enable", true);
		List<SysRoleUser> roleUsers = this.selectList(wrapper);

		List<SysRoleVo> roles = Lists.newArrayList();
		for (SysRoleUser roleUser : roleUsers) {
			SysRole role = this.roleService.selectById(roleUser.getRoleId());
			if (role != null) {
				roles.add(BeanMapper.map(role, SysRoleVo.class));
			}
		}
		return roles;
	}

	@Override
	@Transactional(readOnly = true)
	public List<SysTenantRoleVo> findAllRoleByUserId(Long userId) {
		SysUser user = this.userService.selectById(userId);
		SysTenant tenant = this.tenantService.selectById(user.getTenantId());

		// 查询所有下级机构
		List<SysTenant> subTenants = this.tenantService.findAllSubTenant(tenant.getId());

		// 添加当前机构
		subTenants.add(0, tenant);

		List<SysTenantRoleVo> tenantRoles = Lists.newArrayList();
		for (SysTenant subTenant : subTenants) {
			tenantRoles.add(this.findRoleByUserIdAndTenantId(userId, subTenant.getId()));
		}
		return tenantRoles;
	}

	@Override
	@Transactional(readOnly = true)
	public SysTenantRoleVo findRoleByUserIdAndTenantId(Long userId, Long tenantId) {
		SysTenantRoleVo tenantRoleVo = new SysTenantRoleVo();
		SysTenant tenant = this.tenantService.selectById(tenantId);
		tenantRoleVo.setTenantId(tenant.getId());
		tenantRoleVo.setTenantName(tenant.getName());

		// 查询机构下所有可用角色
		List<SysRole> roles = this.roleService.findRoleListByTenantId(tenantId);
		List<SysRoleVo> roleVos = BeanMapper.mapList(roles, SysRoleVo.class);

		// 查询当前用户已拥有该机构的角色ids
		List<Long> haveRoleIds = this.findUserHaveRoleByTeant(userId, tenantId);

		// 是否选中
		for (SysRoleVo vo : roleVos) {
			boolean check = haveRoleIds.contains(vo.getId()) ? true : false;
			vo.setCheck(check);
		}
		tenantRoleVo.setRoles(roleVos);
		return tenantRoleVo;
	}

	/**
	 * 查询用户指定租户下拥有的角色ids
	 * 
	 * @param userId
	 *            用户ID
	 * @param tenantId
	 *            角色ID
	 * @return
	 */
	private List<Long> findUserHaveRoleByTeant(Long userId, Long tenantId) {
		List<Long> roleIds = Lists.newArrayList();

		Wrapper<SysRoleUser> wrapper = new EntityWrapper<SysRoleUser>();
		wrapper.eq("tenant_id", tenantId).eq("user_id", userId).eq("enable", true);
		List<SysRoleUser> roleUsers = this.selectList(wrapper);
		if (CollectionUtils.isNotEmpty(roleUsers)) {
			for (SysRoleUser roleUser : roleUsers) {
				roleIds.add(roleUser.getRoleId());
			}
		}
		return roleIds;
	}

	@Override
	public void modifyUserRoleByTenant(SysTenantRoleVo tenantRoleVo) {

		List<Long> roleIds = tenantRoleVo.getRoleIds();
		Long userId = tenantRoleVo.getUserId();
		Long tenantId = tenantRoleVo.getTenantId();

		// 删除用户指定租户的角色信息
		this.deleteByTenantId(userId, tenantId);

		List<SysRoleUser> roleUsers = Lists.newArrayList();

		// 再次添加
		if (CollectionUtils.isNotEmpty(roleIds)) {
			for (Long roleId : roleIds) {
				SysRoleUser roleUser = new SysRoleUser();
				roleUser.setEnable(true);
				roleUser.setRoleId(roleId);
				roleUser.setUserId(userId);
				roleUser.setTenantId(tenantId);
				roleUsers.add(roleUser);
			}
		}
		this.insertBatch(roleUsers);
	}

	@Override
	public void modifyUserRoleAll(List<SysTenantRoleVo> tenantRoleVos) {
		if (CollectionUtils.isNotEmpty(tenantRoleVos)) {
			for (SysTenantRoleVo tenantRoleVo : tenantRoleVos) {
				this.modifyUserRoleByTenant(tenantRoleVo);
			}
		}
	}

	@Override
	public void deleteByTenantId(Long userId, Long tenantId) {
		// 删除用户指定租户的角色信息
		Wrapper<SysRoleUser> wrapper = new EntityWrapper<SysRoleUser>();
		wrapper.eq("user_id", userId).eq("tenant_id", tenantId);
		this.delete(wrapper);
	}

	@Override
	public int findUserCountByRoleId(Long roleId) {
		Wrapper<SysRoleUser> wrapper = new EntityWrapper<SysRoleUser>();
		wrapper.eq("role_id", roleId);
		return this.selectCount(wrapper);
	}

	@Override
	public SysRole findUserAdminRole(Long userId) {

		SysUser user = this.userService.selectById(userId);
		SysRole role = this.roleService.findAdminRoleByTenantId(user.getTenantId());

		Wrapper<SysRoleUser> wrapper = new EntityWrapper<SysRoleUser>();
		wrapper.eq("role_id", role.getId()).eq("user_id", userId).eq("tenant_id", user.getTenantId()).eq("enable",
				true);
		SysRoleUser roleUser = this.selectOne(wrapper);

		// 判断当前用户是否拥有
		if (roleUser != null) {
			return role;
		}
		return null;

	}

}
